#include <string.h>
#include <stdlib.h>
#include <stdio.h>
//
#include <signal.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <unistd.h>
#include <arpa/inet.h>
//
#define BUFSIZE 512
int s=0;
ssize_t n=0;
//
void printUsage()
{
  printf("usage: sendc host port step command\n");
}
//

void makeConnection(char *remoteHost, char *port)
{
  struct hostent *host;
  struct sockaddr_in  server;

  host=gethostbyname(remoteHost);
  if(host==NULL){
    u_long addr;
    addr=inet_addr(remoteHost);
    host=gethostbyaddr((char *)&addr,sizeof(addr),AF_INET);
    if(host==NULL){
      perror("gethostbyaddr");
      exit(1);
    }
  }
  memset((char *)&server,0,sizeof(server));
  server.sin_family=AF_INET;
  server.sin_port = htons(atoi(port));
  memcpy((char *)&server.sin_addr,host->h_addr,host->h_length);
  
  if((s=socket(PF_INET,SOCK_STREAM,0))<0){
    perror("socket");
    exit(1);
  }

  if(connect(s, (struct sockaddr *) &server, sizeof(server))<0){
    perror("echoc: connect");
    exit(1);
  }
}

void closeConnection(int a)
{
  if(n==0) return;
  if(s==0) return;
  close(s);
}

int main(int argc, char *argv[]){

  if(argc<=4){
    printUsage();
    exit(1);
  }
  char *remoteHost=argv[1];
  char *port=argv[2];

  setbuf(stdout,NULL);
  setbuf(stderr,NULL);

  signal(SIGINT,closeConnection);
  signal(SIGTERM,closeConnection);

  char buf[BUFSIZE];
  int rc;
  unsigned int ns;
  size_t len;

  ns=atoi(argv[3]);
  if(ns>=9999){
    fprintf(stderr,"invalid step number: %d",ns);
    exit(2);
  }

  makeConnection(remoteHost,port);
  
  strcpy(buf,"CM");                    // header
  sprintf(buf+strlen(buf),"%4.4d",ns); // step number
  strcat(buf,argv[4]);                 // command
  len=strlen(buf);
  buf[len  ]='\r';
  buf[len+1]='\n';
  len += 2;

  n=0;
  if((n=send(s,&buf,len,0))==-1){
    perror("send");
    rc=1;
  }else{
    n=recv(s,&buf,BUFSIZE,0);
    if(n>2){
      n -= 2;
      buf[n]='\0';
      printf("RECV: '%s' [len=%d]\n",buf,(int)n);      
      rc=0;
    }else{
      // unrecognized replay
      rc=2;
    }
  }
  closeConnection(0);
  exit(rc);
}
